#!/usr/bin/python3
import requests
import hashlib
import json
from optparse import OptionParser
import subprocess
import sys

version = '1.0'
sign_js_path = '/usr/local/ts/sign.js'

if sys.version_info < (3, 0):
    sys.stderr.write('ERROR: Python 3.0 or higher required, sorry.')
    sys.exit(1)

def run_cmd(args):
    try:
        result = subprocess.run(args, shell=True, timeout=3, stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=True)
    except Exception as e:
        print('execute:[', e.cmd,'] fail')
        print('return code:', e.returncode)
        print('err msg:',e.stderr.decode('utf8'))
    finally:
        return (result.returncode, result.stdout.decode('utf8'))


def usage():
    # optparser.print_usage()
    optparser.print_version()
    optparser.print_help()

class Translate:
    def translate(self, query, f='', t=''):
        pass

class BaiduTranslate(Translate):
    def __init__(self, appid = '20210208000693793', secret_key = '9U8CXnKQu137wo2_NbWD'):
        self.appid = appid
        self.secret_key = secret_key
        self.salt = '123456789'
        self.baseurl = 'https://fanyi.baidu.com/v2transapi'
        self.headers = {
            "sec-ch-ua":'"Not A;Brand";v="99", "Chromium";v="90", "Microsoft Edge";v="90"',
            "Accept": "*/*",
            "X-Requested-With": "XMLHttpRequest",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)",
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Origin': 'https://fanyi.baidu.com',
            'Referer': 'https://fanyi.baidu.com/?aldtype=16047',
            'Cookie': 'BAIDUID=AFDFDB96D04FC9FFDFCE549EDB5A3626:FG=1'
        }
        self.sign_js_path = sign_js_path
        self.sign = ''

        self.from_lang = 'en'

        self.source = ""
        self.dst = ""
        self.symbols = ''
        self.liju = []

    def getSign(self, query):
        cmd = 'node ' + self.sign_js_path + ' ' + query
        (retcode, data) = run_cmd(cmd)
        if retcode == 0:
            self.sign = data
        return retcode

    def translate(self, query, f='en', t='zh'):
        if query is None or query == '':
            print("query can't empty")
            return 1
        self.from_lang = f
        retcode = self.getSign(query)

        if retcode != 0:
            print('generate sign param error')
            return 1

        query_url_param = 'from=' + f + '&to=' + t
        url = self.baseurl + '?' + query_url_param

        data = {
            "from": f,
            "to": t,
            "query": query,
            "transtype": "realtime",
            "simple_means_flag": 3,
            "sign": self.sign,
            "token": "27effef4f624af927dda8e2f8db39e43",
            "domain": "common"
        }
        # print(json.dumps(data))
        resp = requests.post(url, headers = self.headers, data = data)
        
        if resp.status_code != 200:
            print(resp.text)
            return 1
        result_json = resp.json()
        if "trans_result" not in result_json:
            if "errmsg" in result_json:
                print(result_json["errmsg"])
            else:
                print('request error')
            return 1
        self.source = result_json['trans_result']['data'][0]['src']
        self.dst = result_json['trans_result']['data'][0]['dst']
        self.symbols = result_json['dict_result']['simple_means']["symbols"][0]
        self.liju = json.loads(result_json['liju_result']['double'])

        return 0
    def print(self, options):
        print(self.dst)

        if self.from_lang != 'en':
            return
        if options.phonetic:
            print()
            print('音标:')
            print('英 [', self.symbols["ph_en"] ,'] 美 [', self.symbols["ph_am"] , ']')
        
        if options.simple_means:
            print()
            print('简单释义:')
            if "part" in self.symbols['parts'][0]:
                print(self.symbols['parts'][0]['part'], end='')
            for i in self.symbols['parts'][0]["means"]:
                print(i,';', end='')
            print()

        if options.examples:
            print()
            print('双语例句:')
            self.printLiJu(options)
        
    def printLiJu(self,options):
        count = 0
        num = int(options.examples_num)
        for samples in self.liju:
            if num != -1 and count >= num:
                break

            src_sample = samples[0]
            dst_sample = samples[1]
            for c in src_sample:
                t = c[0]
                if c[3] == 1:
                    t = '\033[32m' + c[0] + '\033[0m'
                print(t,end='')
                if len(c) == 5:
                    print(' ', end='')
            print()
            for c in dst_sample:
                print(c[0], end='')
            print()
            count += 1

if __name__ == '__main__':
    optparser = OptionParser(version="version " + version)
    optparser.add_option("-f", "--from", dest="from_lang", action="store", default="en", help="指定源语言")
    optparser.add_option("-t", "--to", dest="dest_lang", action="store", default="zh", help="指定目标语言")
    optparser.add_option("-p", "--phonetic", dest="phonetic", action="store_false", default=True, help="不显示音标")
    optparser.add_option("-m", "--means", dest="simple_means", action="store_false", default=True, help="不显示简单释义")
    optparser.add_option("-e", "--examples", dest="examples", action="store_true", default=False, help="显示例句")
    optparser.add_option("-n", "--examples-number", dest="examples_num", action="store", default=3, help="显示例句的数量，-1 显示全部")
    # optparser.add_option("-v", "--version", dest="version", action="store_true", help="show version")
    # optparser.add_option("-h", "--help", dest="help", action="store_true", help="show usage")


    optparser.set_usage("%prog [parameters] query")
    optparser.set_description('ts 是一个翻译命令工具，目前只支持中英互翻,主要是英文翻译成中文')
    
    (options, args) = optparser.parse_args()

    if len(args) == 0:
        usage()
        exit(1)

    query = ' '.join(args)

    ts = BaiduTranslate()
    retCode = ts.translate(query, options.from_lang, options.dest_lang)

    if retCode == 0:
        ts.print(options)



